package com.sfdk.admin.data.battleAnimationEditor
{
    import com.sfdk.admin.ApplicationData;
    import com.sfdk.admin.data.RectangleEx;
    import com.sfdk.admin.data.spritesheetEditor.TilePiece;
    import com.sfdk.admin.structure.VectorCollection;
    import com.sfdk.data.api.ITreeDataProvider;
    import com.sfdk.events.IOEvent;
    import com.sfdk.graphics.core.BitmapEx;
    import com.sfdk.io.GenericIO;
    import com.sfdk.pools.BitmapExPool;

    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.utils.Dictionary;

    import mx.collections.ArrayCollection;

    public class BattleAnimationDefinition extends GenericIO implements ITreeDataProvider
    {
        private var _fullName:String;
        private var _type:String;
        private var _rootType:String;
        private var _name:String;

        public function BattleAnimationDefinition(currentDirectory:String = null, filePath:String = null) {
            _fullName = filePath;
            if (filePath != null) {
                var pathArray:Array = filePath.split("/");
                _type = pathArray[pathArray.length - 2];
                _rootType = pathArray[1];
                _name = pathArray[pathArray.length - 1];
            }

            super(currentDirectory + filePath, GenericIO.XML_FILE);
        }

        public static const IDLE_ANIMATION:Object = {label: "Idle", data:"IDLE_ANIMATION"};
        public static const ATTACK_ANIMATION:Object = {label: "Attack", data:"ATTACK_ANIMATION"};
        public static const CRIT_ATTACK_ANIMATION:Object = {label: "Critical Attack", data:"CRIT_ATTACK_ANIMATION"};
        public static const ITEM_USE_ANIMATION:Object = {label: "Item", data:"ITEM_USE_ANIMATION"};
        public static const SPELL_CAST_ANIMATION:Object = {label: "Spell", data:"SPELL_CAST_ANIMATION"};
        public static const SPECIAL_ATTACK_ANIMATION:Object = {label: "Special Attack", data:"SPECIAL_ATTACK_ANIMATION"};
        public static const DODGE_ANIMATION:Object = {label: "Dodge", data:"DODGE_ANIMATION"};
        public static const ANIMATION_LISTS:ArrayCollection = new ArrayCollection([IDLE_ANIMATION, ATTACK_ANIMATION, CRIT_ATTACK_ANIMATION, ITEM_USE_ANIMATION, SPELL_CAST_ANIMATION, SPECIAL_ATTACK_ANIMATION, DODGE_ANIMATION]);
        private static const DEFAULT_ANIMATION_SIZE:int = 10;

        private var _tileList:VectorCollection = new VectorCollection(new Vector.<TilePiece>());
        private var _tileById:Dictionary = new Dictionary();
        private var _bitmapExMap:Dictionary = new Dictionary();

        private var _configuredWeapons:VectorCollection = new VectorCollection(new Vector.<String>());
        private var _toLoad:int;

        private var _characterAnimation:Dictionary = new Dictionary();

        public function get fullName():String {
            return _fullName;
        }


        public function set fullName(value:String):void {
            _fullName = value;
        }

        public function get label():String {
            return _name;
        }

        public function set name(value:String):void {
            _name = value;
        }

        public function get type():String {
            return _type;
        }

        public function get rootType():String {
            return _rootType;
        }

        public function get isImage():Boolean {
            return false;
        }

        public function get imageData():BitmapData {
            return null;
        }

        [Bindable]
        public function get tileList():VectorCollection {
            return _tileList;
        }

        public function get tileById():Dictionary {
            return _tileById;
        }

        [Bindable]
        public function get configuredWeapons():VectorCollection {
            return _configuredWeapons;
        }

        public function set configuredWeapons(value:VectorCollection):void {
            _configuredWeapons = value;
        }

        override protected function init():void {
            var fileXML:XML = _fileInfo;
            var sourcesList:XMLList = fileXML.descendants("file");

            configuredWeapons.addItem("None");

            _toLoad = 0;
            var source:XML;
            for each(source in sourcesList) {
                var bitmapEx:BitmapEx = BitmapExPool.instance.getFromPool(source.@fileName, ApplicationData.BASE_LOCATION + ApplicationData.RESOURCE_DIRECTORY);
                var tilePiece:TilePiece = new TilePiece();
                tilePiece.fileName = source.@fileName;
                tilePiece.id = source.@id;
                _tileById[tilePiece.id] = tilePiece;
                if (!bitmapEx.isLoaded) {
                    _toLoad++;
                    bitmapEx.addEventListener("bitmapExLoaded", onSourceLoaded);
                    _bitmapExMap[bitmapEx] = tilePiece;
                }
                else {
                    var bitmapData:BitmapData = bitmapEx.getImageData();
                    var sourceRectEx:RectangleEx = new RectangleEx(0, 0, bitmapData.width, bitmapData.height);
                    tilePiece.init(bitmapData, sourceRectEx);
                }
                _tileList.addItem(tilePiece);

            }
        }

        private function onSourceLoaded(e:Event):void {
            _toLoad--;
            var bitmapEx:BitmapEx = e.target as BitmapEx;
            var tilePiece:TilePiece = _bitmapExMap[bitmapEx];
            var bitmapData:BitmapData = bitmapEx.getImageData();
            var sourceRectEx:RectangleEx = new RectangleEx(0, 0, bitmapData.width, bitmapData.height);
            tilePiece.init(bitmapData, sourceRectEx);
            if (_toLoad == 0) {
                onAllSourcesLoaded();
            }
        }

        private function onAllSourcesLoaded():void {

            var fileXML:XML = _fileInfo;
            var animationsList:XMLList = fileXML.descendants("animation");
            var animationXML:XML;

            var direction:String;
            var tileId:int;
            var horizontalFlip:Boolean;
            var verticalFlip:Boolean;
            var xOffset:int;
            var yOffset:int;
            var duration:int;

            var battleAnimationFrame:BattleAnimationFrame;
            var subBattleAnimationFrame : BattleAnimationFrame;

            for each(animationXML in animationsList) {
                var type:String = animationXML.@type;
                var characterDefinition:XML = animationXML.characterAnimation[0];
                var tilesDefinition:XMLList = characterDefinition.descendants('tileDefinition');
                var animationCollection : VectorCollection = new VectorCollection(new Vector.<BattleAnimationFrame>());
                for each(var tileXML:XML in tilesDefinition) {
                    tileId = tileXML.@id;
                    horizontalFlip = (tileXML.@horizontalFlip == "true");
                    verticalFlip = (tileXML.@verticalFlip == "true");
                    xOffset = tileXML.@xOffset;
                    yOffset = tileXML.@yOffset;
                    duration = tileXML.@duration;

                    battleAnimationFrame = new BattleAnimationFrame();
                    battleAnimationFrame.id = tileId;
                    battleAnimationFrame.sourceBitmapData = (_tileById[tileId] as TilePiece).bitmapData;
                    battleAnimationFrame.sourceRect = (_tileById[tileId] as TilePiece).sourceRect;
                    battleAnimationFrame.horizontalFlip = horizontalFlip;
                    battleAnimationFrame.verticalFlip = verticalFlip;
                    battleAnimationFrame.xOffset = xOffset;
                    battleAnimationFrame.yOffset = yOffset;
                    animationCollection.addItem(battleAnimationFrame);
                    while(duration > 1)
                    {
                        subBattleAnimationFrame = new BattleAnimationFrame();
                        subBattleAnimationFrame.parentFrame = battleAnimationFrame;
                        animationCollection.addItem(subBattleAnimationFrame);
                        duration--;
                    }
                }
                if(animationCollection.length == 0)
                     animationCollection = new VectorCollection(new Vector.<BattleAnimationFrame>(DEFAULT_ANIMATION_SIZE));
                _characterAnimation[type] = animationCollection;
            }


            dispatchEvent(new IOEvent(IOEvent.LOAD_COMPLETE));
        }


        private function getMaxTileID():int {
            var tilePiece:TilePiece;
            var maxID:int = -1;
            for each(tilePiece in _tileList) {
                if (tilePiece.id > maxID)
                    maxID = tilePiece.id;
            }
            return maxID;
        }

        public function addSource(bitmapEx:BitmapEx):void {
            var tilePiece:TilePiece = new TilePiece();
            var bitmapData:BitmapData = bitmapEx.getImageData();
            var sourceRectEx:RectangleEx = new RectangleEx(0, 0, bitmapData.width, bitmapData.height);

            tilePiece.id = getMaxTileID() + 1;
            tilePiece.fileName = bitmapEx.fullName;
            tilePiece.init(bitmapData, sourceRectEx);

            _tileById[tilePiece.id] = tilePiece;
            _tileList.addItem(tilePiece);
        }


        public function removeSources(selectedItems:Vector.<Object>):void {
            for each(var selectedTilePiece:TilePiece in selectedItems) {
                var index:int = _tileList.getItemIndex(selectedTilePiece);
                if (index != -1) {
                    _tileList.removeItemAt(index);
                    delete _tileById[selectedTilePiece.id];
                }
            }
        }

        public function getCharacterAnimation(data:String):VectorCollection {
            var vectorCollection:VectorCollection = _characterAnimation[data];
            if (vectorCollection == null) {
                vectorCollection = new VectorCollection(new Vector.<BattleAnimationFrame>(DEFAULT_ANIMATION_SIZE));
                _characterAnimation[data] = vectorCollection;
            }
            return vectorCollection;
        }
    }
}